package com.mh.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mh.dao.GroupInfoDao;
import com.mh.dao.GroupUserDao;
import com.mh.dto.R;
import com.mh.dto.bo.UpdateReceiverBo;
import com.mh.dto.vo.CreateGroupVo;
import com.mh.dto.vo.GroupIntoVo;
import com.mh.pojo.GroupInfo;
import com.mh.pojo.GroupUser;
import com.mh.service.GroupInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.UUID;

/**
 * 群组信息表(GroupInfo)表服务实现类
 *
 * @author zmh
 * @since 2024-09-02 17:22:04
 */
@Service
@RequiredArgsConstructor
public class GroupInfoServiceImpl extends ServiceImpl<GroupInfoDao, GroupInfo> implements GroupInfoService {

    @Autowired
    private GroupInfoDao groupInfoDao;

    @Autowired
    private GroupUserDao groupUserDao;

    private final RabbitTemplate rabbitTemplate;

    @Resource
    @Qualifier("redisTemplateSet")
    private RedisTemplate<String, Set<String>> redisTemplateSet;

    // 处理小型应用的不重复ID生成
    private final Set<Integer> groupNumberSet = new HashSet<>(); // 用于存储已生成的群号
    private final Random random = new Random();

    /**
     * 分页查询
     *
     * @param page 查询页数
     * @param size 一页显示条数
     * @return ·
     */
    public R<Page<GroupInfo>> getAllByPage(int page, int size) {
        Page<GroupInfo> groupInfoPage = new Page<>(page, size);
        LambdaQueryWrapper<GroupInfo> queryWrapper = new LambdaQueryWrapper<>();
        //TODO 查询条件定制
        return R.success(groupInfoDao.selectPage(groupInfoPage, queryWrapper));
    }

    /**
     * 创建群组
     * @param createGroupVo VO对象：传入群组名称和群组所属用户ID
     * @return `
     */
    @Override
    public R<String> createGroup(CreateGroupVo createGroupVo) {
        // 生成群号，生成策略：随机生成6位数字（内存级map维护保证不重复）
        int groupNumber = generateUniqueGroupNumber();
        // 构建群组对象，保存数据库
        String groupId = UUID.randomUUID().toString();
        GroupInfo groupInfo = new GroupInfo(null, groupId, createGroupVo.getGroupName(), createGroupVo.getGroupOwner(), groupNumber+"");
        int insertRes = groupInfoDao.insert(groupInfo);

        // 利用MQ动态维护Redis中接收者信息
        UpdateReceiverBo addBo = new UpdateReceiverBo(groupId, createGroupVo.getGroupName(), "add");
        rabbitTemplate.convertAndSend("update-receiver-queue", addBo);

        //（维护Redis中信息）将创建者加入Redis的“群组用户”信息中
        String redisKey = "chat-group:" + groupId;
        Set<String> userIds = redisTemplateSet.opsForValue().get(redisKey);
        if(userIds == null || userIds.isEmpty()) userIds = new HashSet<>();
        userIds.add(createGroupVo.getGroupOwner());
        redisTemplateSet.opsForValue().set(redisKey, userIds);

        // 将创建者添加到新创建的群组中
        GroupUser groupUser = new GroupUser(null, groupId, createGroupVo.getGroupOwner(), 1);
        int insert = groupUserDao.insert(groupUser);

        return insert > 0 ? R.success("创建群组成功") : R.error("创建群组失败");
    }

    /**
     * 根据群号搜搜群组
     * @param groupNumber 群号
     * @return ·
     */
    @Override
    public R<GroupInfo> getGroupInfoByGroupNumber(String groupNumber) {
        LambdaQueryWrapper<GroupInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(GroupInfo::getGroupNumber, groupNumber);
        GroupInfo groupInfo = groupInfoDao.selectOne(queryWrapper);
        return R.success(groupInfo);
    }

    @Override
    public R<Boolean> checkGroupOwner(String groupId, String userId) {
        GroupInfo groupInfo = groupInfoDao.selectOne(new LambdaQueryWrapper<GroupInfo>()
                .eq(GroupInfo::getGroupId, groupId)
                .eq(GroupInfo::getGroupOwner, userId));
        if(groupInfo != null) return R.success(true);
        return R.error("该用户不是该群创建者");
    }

    // 随机生成6位数的群号
    private int generateUniqueGroupNumber() {
        int groupNumber;
        do {
            groupNumber = random.nextInt(900000) + 100000; // 生成6位随机数，范围为100000到999999
        } while (groupNumberSet.contains(groupNumber)); // 检查是否重复
        groupNumberSet.add(groupNumber); // 加入已生成的群号集合
        return groupNumber;
    }
}

